package com.zhj.edu.iotserver.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.zhj.edu.exception.handler.BusinessException;
import com.zhj.edu.iotserver.pay.utils.PayCommonUtil;
import com.zhj.edu.iotserver.pay.utils.PayConfigUtil;
import com.zhj.edu.iotserver.pay.utils.XMLUtil;
import com.zhj.edu.iotserver.service.OrderService;
import com.zhj.edu.iotserver.service.PayService;
import com.zhj.edu.result.ResponseCode;
import com.zhj.edu.vo.PayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Service
@Slf4j
public class PayServiceImpl implements PayService {

    @Autowired
    private OrderService orderService;

    @Override
    public String pay(PayVo payVo, HttpServletRequest req) throws Exception {
        if (null==payVo || null==payVo.getType() || null==payVo.getMoney() || StringUtils.isEmpty(payVo.getOrderNumber()) || StringUtils.isEmpty(payVo.getProductName())){
            throw new BusinessException(ResponseCode.PARAMETER_EXCEPTION.getCode(), ResponseCode.PRODUCT_ID_EXCEPTION.getMsg());
        }
        //参数无误 分类进行支付
        switch (payVo.getType()){
            case 0:
                return weiXinPay(payVo);
                
            case 1:
                return aliPay(payVo);
                
            case 2:
                return unionPay(payVo);
                
        }
        return null;
    }

    /**
     * 银联支付
     * @param payVo
     * @return
     */
    private String unionPay(PayVo payVo) {
        return null;
    }

    /**
     * 支付宝支付
     * @param payVo
     * @return
     */
    private String aliPay(PayVo payVo) {
        return null;
    }

    /**
     * 微信支付
     * @param payVo
     * @return
     */
    private String weiXinPay(PayVo payVo) throws Exception {
        String url = PayCommonUtil.weixin_pay(String.valueOf(payVo.getMoney()), payVo.getProductName(), payVo.getOrderNumber());
        return url;
    }

    @Override
    public void weiXinNotify(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        String writeContent = "默认⽀付失败";
        //从微信请求读取数据
        StringBuffer sb = readWeiXinData(req);
        //将微信服务器传递过来的数据弄成map
        SortedMap<Object, Object> packageParams = convertXMLToMap(sb);
        // 账号信息
        String key = PayConfigUtil.API_KEY; // key
        log.info("微信服务器传递过来的数据是:{}",packageParams);

        //这里获取到的就是咋们的订单号
        String orderNumber = (String) packageParams.get("out_trade_no");//订单号,实际开发中应该在下⾯的 IF 中, 除⾮需要对每个订单的每次⽀付结果做记录
        //判断签名是否正确
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
            String resXml = "";
            if ("SUCCESS".equals((String) packageParams.get("result_code"))) { //支付成功的
                //支付成功的地方
                //TODO 应该将这个支付状态去修改数据库
                orderService.updateOrderStatus(orderNumber,1);
                //通知微信.异步确认成功.必写.不然会⼀直通知后台.⼋次之后就认为交易失败了.
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]> </return_code > "
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {   //支付失败
                //TODO 支付失败的地方 修改数据库的状态
                orderService.updateOrderStatus(orderNumber,2);
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报⽂为空]]></return_msg>" + "</xml> ";
            }
            //------------------------------
            //处理业务完毕
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    resp.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } else {
            writeContent = "订单" + orderNumber + "通知签名验证失败,⽀付失败";//拼接⽀付结果信息, 写⼊⽂件, 实际开发中删除
            System.err.println("通知签名验证失败");
        }


    }

    private static SortedMap<Object, Object> convertXMLToMap(StringBuffer sb) throws Exception {
        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());

        //过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        return packageParams;
    }

    /**
     * 读取微信服务器的数据
     * @param request
     * @return
     * @throws IOException
     */
    private static StringBuffer readWeiXinData(HttpServletRequest request) throws IOException {
        //这里是从请求中获取腾讯服务器 传输过来的参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(
                new InputStreamReader(inputStream,
                        "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        return sb;
    }
}
